#include "stdafx.h"
#include "CAdapter.h"
#include "SPdfPage.h"
#include "PdfPage.h"

CPdfListAdapter::CPdfListAdapter() : m_pPdfDocument(nullptr)
{
  m_tSelectTextInfo.Reset();
  m_dPercent = 1.0;
  m_vecPercents.push_back(0.25);
  m_vecPercents.push_back(0.333);
  m_vecPercents.push_back(0.50);
  m_vecPercents.push_back(0.667);
  m_vecPercents.push_back(0.782);
  m_vecPercents.push_back(1.00);
  m_vecPercents.push_back(1.25);
  m_vecPercents.push_back(1.50);
  m_vecPercents.push_back(2.00);
  m_vecPercents.push_back(3.00);
  m_vecPercents.push_back(4.00);
  m_nRotate = 0;
}

CPdfListAdapter::~CPdfListAdapter()
{
}

int CPdfListAdapter::getCount()
{
  if (m_pPdfDocument)
    return m_pPdfDocument->GetPageCounts();
  return 0;
}

SIZE CPdfListAdapter::getViewDesiredSize(int position, SWindow *pItem, LPCRECT prcContainer)
{
  if (!m_pPdfDocument || position < 0 || position > getCount() - 1) {
    return CSize(10, 10);
  }
  if (m_pPdfDocument) {
    double dWidth = 0, dHeight = 0;
    double width = m_pPdfDocument->GetItemWidth(position);
    double height = m_pPdfDocument->GetItemHeight(position);
    if (m_nRotate == 0 || m_nRotate == 2) {
      dWidth = m_dPercent * width;
      dHeight = m_dPercent * height;
    }
    else {
      dWidth = m_dPercent * height;
      dHeight = m_dPercent * width;
    }
    if (pItem) {
      SItemPanel* pItemPanel = dynamic_cast<SItemPanel*>(pItem);
      SListView *pListView = dynamic_cast<SListView*>(pItemPanel->GetHostWindow());
      SWindow *pdfContainer = pItem->FindChildByName2<SWindow>("pdf_container");
      //SPdfPage *pdfpage = pItem->FindChildByName2<SPdfPage>("pdf_page");
      CRect rt = pListView->GetClientRect();
      wchar_t pszPos[64] = { 0 };
      if (rt.Width() < (int)dWidth) {
        wsprintf(pszPos, L"0,0,@%d,@%d", int(dWidth), int(dHeight));
        pdfContainer->SetAttribute(_T("pos"), pszPos);
      }
      else {
        wsprintf(pszPos, L"|%d,%d,|%d,@%d", -int(dWidth / 2), 0, int(dWidth / 2), int(dHeight));
        pdfContainer->SetAttribute(_T("pos"), pszPos);
      }
    }
    return CSize(static_cast<int>(dWidth), static_cast<int>(dHeight));
  }
  return CSize(10, 10);
}

void CPdfListAdapter::getView(int position, SWindow * pItem, pugi::xml_node xmlTemplate)
{
  if (pItem->GetChildrenCount() == 0)
  {
    pItem->InitFromXml(xmlTemplate);
  }
  SPdfPage* pdfpage = pItem->FindChildByName2<SPdfPage>(L"pdf_page");
  pdfpage->SetUserData(position);
}

void CPdfListAdapter::SetPdfDocument(std::shared_ptr<PdfDocument> document)
{
  m_pPdfDocument = document;
}

std::shared_ptr<PdfDocument> CPdfListAdapter::GetPdfDocument() const
{
  return m_pPdfDocument;
}

SelectTextInfo& CPdfListAdapter::GetSelectTextInfo()
{
  return m_tSelectTextInfo;
}

std::wstring CPdfListAdapter::GetSelectText()
{
  std::wstring strText = L"";
  if (!m_tSelectTextInfo.IsLegal())
    return strText;

  PdfPage* pPage = nullptr;
  for (int i = m_tSelectTextInfo.nStartPage; i <= m_tSelectTextInfo.nEndPage; ++i)
  {
    pPage = m_pPdfDocument->GetPdfPage(i);
    int nTextStartIndex, nTextEndIndex;
    if (m_tSelectTextInfo.nStartPage == i)
      nTextStartIndex = m_tSelectTextInfo.nStartIndex;
    else if (m_tSelectTextInfo.nStartPage < i)
      nTextStartIndex = 0;
    else
      nTextStartIndex = FPDFText_CountChars(pPage->GetTextPage());

    if (m_tSelectTextInfo.nEndPage == i)
      nTextEndIndex = m_tSelectTextInfo.nEndIndex;
    else if (m_tSelectTextInfo.nEndPage < i)
      nTextEndIndex = 0;
    else
      nTextEndIndex = FPDFText_CountChars(pPage->GetTextPage());

    int nStart = nTextStartIndex;
    int nCounts = nTextEndIndex + 1 - nTextStartIndex;
    if (nTextStartIndex > nTextEndIndex)
    {
      nStart = nTextEndIndex;
      nCounts = nTextStartIndex + 1 - nTextEndIndex;
    }
    wchar_t* result = new wchar_t[nCounts + 1];
    memset(result, 0, (nCounts + 1) * sizeof(wchar_t));
    FPDFText_GetText(pPage->GetTextPage(), nStart, nCounts, (unsigned short*)result);
    strText += result;
    delete[] result;
  }
  return strText;
}

void CPdfListAdapter::ZoomInOrOut(bool bFlag)
{
  if (bFlag) {
    for (int i = 0; i < (int)m_vecPercents.size(); i++) {
      if (m_vecPercents[i] - m_dPercent > FZERO) {
        m_dPercent = m_vecPercents[i];
        break;
      }
    }
  }
  else {
    for (int i = m_vecPercents.size() - 1; i >= 0; i--) {
      if (m_vecPercents[i] - m_dPercent < -FZERO) {
        m_dPercent = m_vecPercents[i];
        break;
      }
    }
  }
}

double CPdfListAdapter::GetScale() const
{
  return m_dPercent;
}

void CPdfListAdapter::RotateLeftOrRight(bool bFlag)
{
  if (bFlag)
    ++m_nRotate;
  else
    --m_nRotate;
  m_nRotate = (m_nRotate + 4) % 4;
  //notifyDataSetChanged();
}

int CPdfListAdapter::GetRotate() const
{
  return m_nRotate;
}

void CPdfListAdapter::PageToDevice(FPDF_PAGE page, const CRect& rcDisplay, int rotate, const CRect& rcIn, CRect& rcOut)
{
  int nDeviceLeft, nDeviceTop, nDeviceRight, nDeviceBottom;
  FPDF_PageToDevice(page, rcDisplay.left, rcDisplay.top, rcDisplay.Width(), rcDisplay.Height(), rotate, rcIn.left, rcIn.top, &nDeviceLeft, &nDeviceTop);
  FPDF_PageToDevice(page, rcDisplay.left, rcDisplay.top, rcDisplay.Width(), rcDisplay.Height(), rotate, rcIn.right, rcIn.bottom, &nDeviceRight, &nDeviceBottom);
  if (rotate == 0)
  {
    rcOut.left = nDeviceLeft;
    rcOut.top = nDeviceTop;
    rcOut.right = nDeviceRight;
    rcOut.bottom = nDeviceBottom;
  }
  else if (rotate == 1)
  {
    rcOut.left = nDeviceRight;
    rcOut.top = nDeviceTop;
    rcOut.right = nDeviceLeft;
    rcOut.bottom = nDeviceBottom;
  }
  else if (rotate == 2)
  {
    rcOut.left = nDeviceRight;
    rcOut.top = nDeviceBottom;
    rcOut.right = nDeviceLeft;
    rcOut.bottom = nDeviceTop;
  }
  else if (rotate == 3)
  {
    rcOut.left = nDeviceLeft;
    rcOut.top = nDeviceBottom;
    rcOut.right = nDeviceRight;
    rcOut.bottom = nDeviceTop;
  }
}
